<?php

/**
 * 定时任务接口
 * 
 * 以Crontab方式每分钟定时执行,且只可以CLI方式运行
 * @internal
 */
class AutotaskController extends Controller {

    /**
     * 时间信息
     * @var array 
     */
    protected $info;

    /**
     * 初始化方法,最前且始终执行
     */
    public function init() {
        //只可以以cli方式执行
        if (!$this->_request->isCli())
            exit('Autotask script only work at client!');
        Yaf_Dispatcher::getInstance()->disableView();
        Logger::getInstance()->start('autotask');
        $this->info = array('time' => time(), 'year' => date('Y'), 'month' => date('m'), 'day' => date('d'), 'hour' => date('H'), 'minute' => date('i'), 'second' => date('s'));
        //清除错误
        error_reporting(0);
        //设置永不超时
        set_time_limit(0);
    }

    /**
     * 执行定时任务
     */
    public function indexAction() {
        $time = $this->redis->exists('autotasktime') ? $this->redis->get('autotasktime') : $this->info['time'] - 60;
        $data = array('year' => date('Y', $time), 'month' => date('m', $time), 'day' => date('d', $time), 'hour' => date('H', $time), 'minute' => date('i', $time));
        //每分钟
        if ($this->info['minute'] != $data['minute']) {
            $this->redis->set('autotasktime', $this->info['time']);
            try {
                $this->minuteAction();
            } catch (Exception $e) {
                Logger::getInstance()->error($e);
            }
        }
        //每小时
        if ($this->info['hour'] != $data['hour'] && $this->info['minute'] == '00') {
            try {
                $this->hourAction();
            } catch (Exception $e) {
                Logger::getInstance()->error($e);
            }
        }
        //每天
        if ($this->info['day'] != $data['day'] && $this->info['hour'] == '00' && $this->info['minute'] == '00') {
            try {
                $this->dayAction();
            } catch (Exception $e) {
                Logger::getInstance()->error($e);
            }
        }
        Logger::getInstance()->stop('autotask', TRUE);
    }

    //每1分钟
    private function minuteAction() {
        $this->_crontab();
    }

    //每小时
    private function hourAction() {
        
    }

    //每天凌晨
    private function dayAction() {
        
    }

    /**
     * 定时任务处理
     */
    private function _crontab() {
        define('GAME_STATUS_NORMAL', 'normal');
        define('GAME_STATUS_HIDDEN', 'hidden');
        define('GAME_STATUS_EXPIRED', 'expired');
        define('GAME_STATUS_COMPLETED', 'completed');
        define('GAME_STATUS_FINISHED', 'finished');
        //筛选未过期且未完成的任务
        $crontablist = $this->db->all("SELECT * FROM {pre}crontab WHERE status IN ('" . GAME_STATUS_NORMAL . "') ORDER BY weigh DESC");
        foreach ($crontablist as $row) {
            $update = array();
            $execute = FALSE;
            if ($row['frequence'] == 'once') {
                if ($row['starttime'] > $this->info['time'])
                    continue;
                $execute = TRUE;
            } else {
                if ($this->info['time'] < $row['starttime']) {
                    //任务未开始
                } else if ($row['maximums'] && $row['executes'] > $row['maximums']) {
                    //任务已超过最大执行次数
                    $update['status'] = GAME_STATUS_FINISHED;
                } else if ($row['expiretime'] && $this->info['time'] > $row['expiretime']) {
                    //任务已过期
                    $update['status'] = GAME_STATUS_EXPIRED;
                } else {
                    //重复执行
                    //如果未到执行时间则继续循环
                    if (!Tools::isTimeCron($this->info['time'], $row['crontab']))
                        continue;
                    $execute = TRUE;
                }
            }
            //如果允许执行
            if ($execute) {
                $update['executetime'] = $this->info['time'];
                $update['executes'] = $row['executes'] + 1;
                $update['status'] = $row['frequence'] == 'once' || ($row['maximums'] && $update['executes'] >= $row['maximums']) ? GAME_STATUS_FINISHED : GAME_STATUS_NORMAL;
                try {
                    if ($row['type'] == 'notice') {
                        //发送滚动通知
                        //Tools::sendToClient("10--3", array(array('msg' => $row['content'], 'queue' => 8, 'count' => 1, 'interval' => 1)), $row['receiver_user_ids']);
                    } else if ($row['type'] == 'module') {
                        list($module, $controller, $action) = explode('/', trim($row['content'], '/'));
                        $this->forward($module, $controller, $action);
                    } else if ($row['type'] == 'url') {
                        //调用URL
                        Tools::sendAsyncRequest($row['content']);
                    } else if ($row['type'] == 'clearcache') {
                        //清楚缓存
                        $this->cache->clear();
                    }
                } catch (Exception $e) {
                    Logger::getInstance()->error($e);
                }
            }
            //如果需要更新状态
            if ($update) {
                $this->db->update("{pre}crontab", $update, array('id' => $row['id']));
            }
        }
    }

    public function monitorAction() {
        echo "ok";
    }

}
